#include <bits/stdc++.h>
#define re register

using namespace std;

const int N = 1e5 + 10,M = N * 2;
int n,m,k;
bool vis[N],mark[N];
int dep[N],f[N],fp[N];
int idx,h[N],ne[M],e[M];
vector<int> g[N];
vector<vector<int>> ans;

inline int read(){
    int r = 0,w = 1;
    char c = getchar();
    while (c < '0' || c > '9'){
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9'){
        r = (r << 3) + (r << 1) + (c ^ 48);
        c = getchar();
    }
    return r * w;
}

inline void add(int a,int b){
    ne[idx] = h[a];
    e[idx] = b;
    h[a] = idx++;
}

inline int lca(int x,int y){
    if (dep[x] < dep[y]) swap(x,y);
    while (dep[x] != dep[y]) x = fp[x];
    if (x == y) return x;
    while (fp[x] != fp[y]) x = fp[x],y = fp[y];
    return fp[x];
}

inline vector<int> getpath(int x,int y){
    vector<int> a,b;
    int gf = lca(x,y);
    // cerr << x << " " << y << " " << gf << " " << dep[x] << " " << dep[y] << " " << dep[gf] << " ???\n";
    // assert(dep[x] >= dep[gf] && dep[y] >= dep[gf]);
    for (re int i = x;i != gf;i = fp[i]) a.push_back(i);
    // for (re int i = x;i != gf;i = fp[i]){
    //     if (x == 40475) cerr << i << " " << fp[i] << " jump1\n";
    // }
    // cerr << "finish1\n";
    // for (re int i = y;i != gf;i = fp[i]){
    //     cerr << i << " sbsb\n";
    //     if (x == 40475) cerr << i << " " << fp[i] << " jump2\n";
    //     break;
    // }
    // cerr << "finish2\n";
    for (re int i = y;i != gf;i = fp[i]) b.push_back(i);
    a.push_back(gf); reverse(b.begin(),b.end());
    for (int x:b) a.push_back(x);
    // cerr << a.size() << " ???\n";
    return a;
}

inline void dfs1(int u,int fa){
    vis[u] = true;
    dep[u] = dep[fp[u] = fa] + 1;
    for (re int i = h[u];~i;i = ne[i]){
        int v = e[i];
        if (vis[v]) continue;
        dfs1(v,u); g[u].push_back(v);
        // cerr << u << " " << v << "\n";
    }
}

inline void dfs2(int u){
    int res = 0;
    vis[u] = true;
    // cerr << u << " !!!\n";
    for (int v:g[u]){
        dfs2(v);
        // cerr << u << " " << v << " " << f[v] << " ???\n";
        if (f[v]){
            if (!res) res = f[v];
            else{ ans.push_back(getpath(f[v],res)); res = 0; }
        }
    }
    if (mark[u]){
        if (!res) res = u;
        else{ ans.push_back(getpath(u,res)); res = 0; }
    } f[u] = res;
}

int main(){
    freopen("travel.in","r",stdin);
    freopen("travel.out","w",stdout);
    memset(h,-1,sizeof(h));
    n = read(),m = read(),k = read();
    for (re int i = 1,a,b;i <= m;i++){
        a = read(),b = read();
        add(a,b); add(b,a);
    }
    for (re int i = 1;i <= k;i++) mark[read()] = true;
    for (re int i = 1;i <= n;i++){
        if (!vis[i]) dfs1(i,0);
    } fill(vis,vis + n + 1,false);
    for (re int i = 1;i <= n;i++){
        if (!vis[i]) dfs2(i);
    } printf("%d\n",ans.size());
    for (vector<int> v:ans){
        printf("%d ",v.size());
        for (int x:v) printf("%d ",x);
        puts("");
    }
    return 0;
}

/*
大胆猜测一个连通块跑出任意 dfs 树就一定可以做到最大
*/